/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package run;

import algorithm.Algorithm;
import algorithm.AlgorithmErrorException;
import algorithm.BreedingSelector;
import algorithm.Environment;
import algorithm.ObjectiveFunction;
import algorithm.PopulationBreeder;
import algorithm.PopulationInitializer;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import multiplealgo.HierarchyAlgo;
import simple.BitStringPopulationInitializer;
import simple.CrossOverOperator;
import simple.DefaultPopulationBreeder;
import simple.DoubleArrayBitStringEncoder;
import simple.LogGenerationReport;
import simple.MutationBreeder;
import simple.NumberOfGenerationsStopCriterion;
import simple.RankRouletteWheelSelector;
import simple.SimpleGeneticAlgorithm;
import testutil.MultiMinimumTestObjectiveFunction;
import testutil.MultiMinimumTestObjectiveFunctionSingleDimension;

/**
 *
 * @author vermaak
 */
public class RunToughHierarchyGA extends TestCase {
    private int nValues = 3;
    private int bitsPerValue = 16;

    public void testHierarchy() throws AlgorithmErrorException {
        final int nGenerations = 100;
        int populationSize = 100;

        List<Algorithm> subAlgos = new ArrayList<Algorithm>();
        // set up a GA that cares only about the first digit
        subAlgos.add(createAlgo(new MultiMinimumTestObjectiveFunctionSingleDimension(0)));
        // set up a GA that cares only about the last digit
        subAlgos.add(createAlgo(new MultiMinimumTestObjectiveFunctionSingleDimension(1)));

        // the final GA cares about both digits
        PopulationInitializer initializer = new BitStringPopulationInitializer(populationSize, bitsPerValue*nValues);
        BreedingSelector selector = new RankRouletteWheelSelector();
        PopulationBreeder crossOverBreeder = new DefaultPopulationBreeder(
                selector,
                new CrossOverOperator());
        Environment environment = new Environment(new MultiMinimumTestObjectiveFunction(), new DoubleArrayBitStringEncoder(bitsPerValue, nValues));

        HierarchyAlgo hierarchy = new HierarchyAlgo(
                initializer,
                new NumberOfGenerationsStopCriterion(nGenerations),
                crossOverBreeder,
                null,
                environment,
                subAlgos);
        
        hierarchy.addGenerationReport(new LogGenerationReport());
        
        hierarchy.run();
    }

    private Algorithm createAlgo(ObjectiveFunction objective) {
        final int nGenerations = 100;
        double mutationChance = 0.05;
        double mutationFraction = 0.05;
        int populationSize = 100;

        PopulationInitializer initializer = new BitStringPopulationInitializer(populationSize, bitsPerValue*nValues);
        BreedingSelector selector = new RankRouletteWheelSelector();
        PopulationBreeder crossOverBreeder = new DefaultPopulationBreeder(
                selector,
                new CrossOverOperator());
        PopulationBreeder mutator = new MutationBreeder(mutationChance, mutationFraction);

        Environment environment = new Environment(objective, new DoubleArrayBitStringEncoder(bitsPerValue, nValues));

        SimpleGeneticAlgorithm algo = new SimpleGeneticAlgorithm(
                initializer,
                new NumberOfGenerationsStopCriterion(nGenerations),
                crossOverBreeder,
                mutator,
                environment);

        return algo;
    }
}
